package top.mccat.filesystem.controller;

import com.auth0.jwt.JWT;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.mccat.filesystem.anno.CurrentAccount;
import top.mccat.filesystem.anno.UserLoginToken;
import top.mccat.filesystem.bean.Account;
import top.mccat.filesystem.bean.FileMenu;
import top.mccat.filesystem.bean.MyFile;
import top.mccat.filesystem.bean.TreeMenu;
import top.mccat.filesystem.mapper.AccountMapper;
import top.mccat.filesystem.mapper.FileMapper;
import top.mccat.filesystem.mapper.FileMenuMapper;
import top.mccat.filesystem.service.FileMenuService;
import top.mccat.filesystem.service.FileService;
import top.mccat.filesystem.utils.AjaxResult;
import top.mccat.filesystem.utils.io.FileUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Raven
 */
@RestController
@RequestMapping("/file")
@Slf4j
public class FileIoController {

    @Autowired
    private FileUtils fileUtils;

    @Autowired
    private FileService fileService;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private FileMenuService fileMenuService;

    @Autowired
    private FileMenuMapper fileMenuMapper;

    @Value("${pageSize}")
    private Integer pageSize;

    /**
     * 上传文件方法
     * @param file
     * @param fileRemark
     * @param fileParent
     * @param request
     * @param account
     * @return
     */
    @UserLoginToken
    @PostMapping("/upload")
    public AjaxResult upload(@RequestBody MultipartFile[] file, String fileRemark, Integer fileParent, HttpServletRequest request, @CurrentAccount Account account) {
        try {
            fileService.uploadFile(file, fileRemark, fileParent, Long.parseLong(account.getUserName()), false);
            log.debug("上传成功");
        } catch (FileAlreadyExistsException e) {
            e.printStackTrace();
            log.warn(e.getMessage());
            return AjaxResult.errorResult("文件已存在，请上传其他文件！");
        } catch (IOException e) {
            e.printStackTrace();
            log.warn(e.getMessage());
            return AjaxResult.errorResult("服务器后台上传错误，请联系工作人员");
        }
        return AjaxResult.successResult("上传成功！");
    }

    /**
     * 列举所有文件方法
     * @param file
     * @param pageNum
     * @param account
     * @return
     */
    @UserLoginToken
    @GetMapping("/list")
    public AjaxResult listFile(MyFile file, @RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum , @CurrentAccount Account account){
        //查看当前账户是否为admin账户，如果是则让其查看所有文件
        Account current = accountMapper.selectAccount(account);
        PageInfo<MyFile> myFilePageInfo;
        PageHelper.startPage(pageNum,pageSize);
        if(current.getIsAdmin()){
            //无视author即可查看所有文件，当前用户为自己的时候，清空查看所有，如果有查看指定用户
            myFilePageInfo = new PageInfo<>(fileMapper.selectFileAdmin(file));
        }else {
            //不为admin则设置其为当前用户本身
            file.setFileAuthor(Long.valueOf(account.getUserName()));
            myFilePageInfo = new PageInfo<>(fileMapper.selectFile(file));
        }
        return AjaxResult.successResult("查询成功", myFilePageInfo);
    }

    /**
     * 下载方法
     * @param file
     * @param response
     * @param account
     * @throws IOException
     */
    @UserLoginToken
    @GetMapping("/download")
    public void getFile(MyFile file, HttpServletResponse response, @CurrentAccount Account account) throws IOException {
        log.debug("account: {}",account);
        file.setFileAuthor(Long.parseLong(account.getUserName()));
        fileService.downloadFile(file, response);
        log.debug("下载成功");
    }

    /**
     * 列出菜单
     * @param account
     * @param parentId
     * @return
     */
    @UserLoginToken
    @GetMapping("/trees")
    public AjaxResult getTreeMenu(@CurrentAccount Account account, int parentId){
        List<FileMenu> menus;
        //如果为懒加载最上级直接给与menuLevel为0的参数（即最高级）
        if(parentId == 0){
            menus = fileMenuService.queryByFileLevel(0);
            return AjaxResult.successResult("获取最高级menu成功",menus);
        }
        menus = fileMenuService.queryLazy(parentId);
        //如果最大等级一样则设置当前为叶子节点
        //放弃使用该方法，直接将其是否为叶子节点放到数据库
        /*int maxLevel = fileMenuMapper.maxLevel();
        menus.forEach(menu -> menu.setLeaf(menu.getTreeLevel() == maxLevel));*/
        return AjaxResult.successResult("获取menu成功",menus);
    }

    @UserLoginToken
    @PostMapping("/move")
    public AjaxResult updateTreeMenu(@CurrentAccount Account account,@RequestBody FileMenu fileMenu){
        Account current = accountMapper.selectAccount(account);
        if(!current.getIsAdmin()){
            return AjaxResult.errorResult("错误，当前账户无法进行菜单修改操作！");
        }
        FileMenu update = fileMenuService.update(fileMenu);
        return AjaxResult.successResult("修改成功",update);
    }

    /**
     * 删除操作
     * @param file
     * @param account
     * @return
     */
    @UserLoginToken
    @PostMapping("/delete")
    public AjaxResult deleteFile(@RequestBody MyFile file,@CurrentAccount Account account){
        //判断当前账号是否为admin，如果为admin可以跨用户删除文件
        Account current = accountMapper.selectAccount(account);
        if(!current.getIsAdmin()){
            file.setFileAuthor(Long.valueOf(account.getUserName()));
        }
        try {
            fileService.deleteFile(file);
        } catch (FileNotFoundException e){
            e.printStackTrace();
            log.warn(e.getMessage());
            return AjaxResult.errorResult("文件不存在，请确定文件存在！");
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("删除失败，服务器错误！");
        }
        log.debug("删除成功！");
        return AjaxResult.successResult("删除成功！");
    }
}
